package com.alm.handle.util;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.internal.StringUtil;
import org.springframework.util.StringUtils;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class InstructionByteUtils {
    //头是固定的
    private static final byte[] finalHead = new byte[]{0x41, 0x4c, 0x4d};
    //六个字节是固定的
    // private static final byte [] finalDev=new byte[]{00,00,00,00,00,00};


    /**
     * 指令下发 前半部分拼接（前半部分是固定的）
     *
     * @param dcId     设备编号  设备ID的hex编码
     * @param dcTypeId 设备类型 设备类别hex编码
     * @param dcNOId   设备序号 设备序码hex编码
     * @return 拼接返回前半部分
     */

    public static ByteBuf getBFBYTEInstruction(String dcId, Short dcTypeId, Short dcNOId) {
        ByteBuf databuf = Unpooled.buffer(4);
        databuf.writeBytes(
                getToZeroByArray(
                        toByteArray(Long.parseLong(dcId, 16)
                        )));
        databuf.writeShort(dcTypeId);
        //databuf.writeShort(dcNOId);
        return databuf;
    }

    public static byte[] getBYTEISBYTES(ByteBuf befor, byte[] datas) {
        ByteBuf buf = Unpooled.buffer(4);
        byte[] bytes = null;
        try {
            buf.writeBytes(finalHead);
            befor.writeBytes(datas);
            int lenth = finalHead.length + befor.readableBytes();
            lenth += 2;
            buf.writeShort(lenth);
            //  buf.writeBytes(finalDev);
            buf.writeBytes(befor);
            bytes = new byte[buf.readableBytes()];
            buf.readBytes(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            buf.release();
            befor.release();
        }
        return bytes;
    }

    /**
     * @param head
     * @param devType
     * @param icType
     * @param data
     * @param tail
     * @return
     */
//    2301B03A0585803A1000005E20000000003A3137A02840005E500000000XX000000000E
    public static byte[] getBYTEISData(int head, int devType,
                                       int icType, byte[] data, int tail) {
        int lth = data.length; // data总长度
        byte lthbyte = (byte) lth;
        ByteBuf databuf = Unpooled.buffer(4);//拼接data
        databuf.writeByte(devType);
        databuf.writeByte(icType);
        databuf.writeByte(lthbyte);
        databuf.writeBytes(data);
        databuf.writeShort(tail);
        int sumlth = databuf.readableBytes();
        byte sumlthbyte = (byte) sumlth;
        ByteBuf buf = Unpooled.buffer(4);//最后返回的数据
        buf.writeShort(head);//头
        buf.writeByte(sumlthbyte); //总长度
        buf.writeBytes(databuf);//data 数据
        byte[] databytes = new byte[buf.readableBytes()];
        buf.readBytes(databytes);
        databuf.release();
        buf.release();
        return databytes;
    }

    /**
     * 剔除空元素
     *
     * @param old
     * @return
     */
    public static byte[] getToZeroByArray(byte[] old) {
        int zero = 0;  // 统计0的个数
        int number = 0;
        for (int i = 0; i < old.length; i++) {
            if (old[i] == 0 && number == 0) {
                zero++;
            }
            if (number == 0 && old[i] > 0) {
                number = old[i];
            }
        }
        byte newArr[] = new byte[old.length - zero];  // 定义新的数组 长度是 原来旧的数组的长度减去0的个数
        int j = 0;  // 新数组的索引
        for (int i = zero; i < old.length; i++) {  // 遍历原来旧的数组
            newArr[j] = old[i];  // 赋值给新的数组
            j++;
        }
        return newArr;
    }

    /**
     * 将long 转为数组
     *
     * @param value
     * @return
     */
    public static byte[] toByteArray(long value) {
        return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(value).array();
    }


    public static List<byte[]> getByteByName(String namedatas) {
        if (Objects.isNull(namedatas) || namedatas.length() <= 1) {
            return new ArrayList<byte[]>();
        }
        List<byte[]> namedata = new ArrayList<byte[]>();
        String[] names = namedatas.split(",");
        for (String name : names) {
            if (StringUtil.isNullOrEmpty(name)) {
                continue;
            }
            namedata.add(name.getBytes());

        }
        return namedata;
    }

    public static List<byte[]> getByteByMac(String namedatas) {
        if (Objects.isNull(namedatas) || namedatas.length() <= 1) {
            return new ArrayList<byte[]>();
        }
        List<byte[]> namedata = new ArrayList<byte[]>();
        String[] names = namedatas.split(",");
        for (String name : names) {
            namedata.add(
                    getToZeroByArray(
                            toByteArray(Long.parseLong(name, 16)
                            ))
            );
        }
        return namedata;
    }

    public static short byteArrayToShort(byte[] bytes, int start, boolean isBig) {
        short value = 0;
        if (isBig) {
            value += (bytes[start] & 0x000000FF) << 8;
            value += (bytes[start + 1] & 0x000000FF);
        } else {
            value += (bytes[start] & 0x000000FF);
            value += (bytes[start + 1] & 0x000000FF) << 8;
        }
        return value;
    }

    /**
     * @param deviceId   设备Mac地址
     * @param deviceType 设备类型
     * @return
     */
    public static ByteBuf beforeData(String deviceId, Short deviceType) {
        final byte[] bytes = new byte[deviceId.length()>>1];
        final byte[] array = ByteBuffer.allocate(Long.SIZE>>3).putLong(Long.parseLong(deviceId, 16)).array();
        System.arraycopy(array,(Long.SIZE>>3)-bytes.length,bytes,0,bytes.length);
        return Unpooled.buffer(4)
                .writeBytes(bytes)
                .writeShort(deviceType);
    }

    /**
     *
     * @param head 数据头
     * @param devType 设备类型
     * @param icType  //指令类型
     * @param data   //数据体
     * @param tail  //尾巴：时间戳类型+校验和
     * @return
     */
    public static byte[] afterData(int head, int devType,int icType, byte[] data, int tail){
        byte dataLen = (byte) data.length;
        final ByteBuf buf = Unpooled.buffer(4);
        buf.writeByte(devType)
                .writeByte(icType)
                .writeByte(dataLen)
                .writeBytes(data)
                .writeShort(tail);
        final ByteBuf buffer = Unpooled.buffer(4);
        final int dataTotalLen = buf.readableBytes();
        buffer.writeShort(head).writeByte(dataTotalLen);
        buffer.writeBytes(buf);
        final byte[] bytes = new byte[buffer.readableBytes()];
        buffer.readBytes(bytes);
        buf.release();
        buffer.release();
        return bytes;
    }

    public static byte[] finalByteArrayInstruction(ByteBuf beforeData,byte[] afterData){
        final short totalLen = (short) (finalHead.length+2+beforeData.readableBytes()+afterData.length);
        ByteBuf buf = Unpooled.buffer(4).writeBytes(finalHead).writeShort(totalLen).writeBytes(beforeData).writeBytes(afterData);
        final byte[] bytes = new byte[buf.readableBytes()];
        buf.readBytes(bytes);
        buf.release();
        return bytes;
    }
    public static byte[] hexStrToBytes(String str) {
        if (str == null || str.trim().equals("")) {
            return new byte[0];
        }
        str = StringUtils.replace(str, ",", "");
        final byte[] bytes = new byte[str.length() / 2];
        for (int i = 0; i < str.length() / 2; i++) {
            final String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }
        return bytes;
    }
}
